﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Microsoft.Forums.OfflineStore
{
    /// <summary>
    /// Methods to deal with creation and maintinence of the database
    /// </summary>
    public static class DatabaseUtilities
    {

        /// <summary>
        /// Doeses the database exist.
        /// </summary>
        /// <param name="connectionString">The connection string.</param>
        /// <returns>True if it exists</returns>
        public static bool DoesDatabaseExist(string connectionString)
        {
            if (String.IsNullOrEmpty(connectionString)) throw new ArgumentNullException("connectionString", "connectionString cannot be null");

            var dbContext = new ForumsOfflineStore(connectionString);
            return dbContext.DatabaseExists();
        }

        /// <summary>
        /// Does the existing database match the current versionversion.
        /// </summary>
        /// <param name="connectionString">The connection string.</param>
        /// <returns></returns>
        public static bool DoesDatabaseMatchCurrentVersion(string connectionString)
        {
            if (String.IsNullOrEmpty(connectionString)) throw new ArgumentNullException("connectionString", "connectionString cannot be null");

            var dbContext = new ForumsOfflineStore(connectionString);
            return dbContext.ClientConfigurations.Any(
                    r => r.Name.Equals(Properties.Resources.DatabaseVersionFieldName) &&
                         r.Value.Equals(Properties.Resources.DatabaseVersion));
        }

        /// <summary>
        /// Create a new .sdf database file 
        /// If the database (specified by the connection string) does exist, overwrite it
        /// </summary>
        /// <param name="connectionString">the connection string for the database</param>
        public static void CreateNewDatabase(string connectionString)
        {
            if (String.IsNullOrEmpty(connectionString)) throw new ArgumentNullException("connectionString", "connectionString cannot be null");

            var dbContext = new ForumsOfflineStore(connectionString);
            if (dbContext.DatabaseExists())
                dbContext.DeleteDatabase();

            CreateDatabaseWithVersionInfo(connectionString);
        }


        /// <summary>
        /// Creates the database with version info.
        /// Pre-Condition: Database does NOT exist
        /// </summary>
        /// <param name="connectionString">The connection string.</param>
        /// <param name="version">The version.</param>
        private static void CreateDatabaseWithVersionInfo(string connectionString)
        {
            var dbContext = new ForumsOfflineStore(connectionString);
            dbContext.CreateDatabase();
            CreateDatabaseIndexes(dbContext);
            dbContext.ClientConfigurations.InsertOnSubmit(
                new ClientConfiguration()
                {
                    Name = Properties.Resources.DatabaseVersionFieldName,
                    Value = Properties.Resources.DatabaseVersion
                });
            dbContext.SubmitChanges();
        }


        /// <summary>
        /// Creates the database indexes.
        /// </summary>
        private static void CreateDatabaseIndexes(ForumsOfflineStore store)
        {
            List<string> indexCreationQueries = new List<string>();
            indexCreationQueries.Add("CREATE INDEX IX_Forums_ForumServiceProviderId ON Forums(ForumServiceProviderId)");
            indexCreationQueries.Add("CREATE INDEX IX_Threads_ForumId ON Threads(ForumId)");
            indexCreationQueries.Add("CREATE INDEX IX_Posts_ForumId ON Posts(ForumId)");
            indexCreationQueries.Add("CREATE INDEX IX_Posts_ThreadId ON Posts(ThreadId)");
            indexCreationQueries.Add("CREATE INDEX IX_Posts_ParentId ON Posts(ParentId)");
            indexCreationQueries.Add("CREATE INDEX IX_Posts_ThreadModifiedOn ON Posts(ThreadModifiedOn)");
            indexCreationQueries.Add("CREATE INDEX IX_Posts_CreatedById ON Posts(CreatedById)");

            foreach (var query in indexCreationQueries)
            {
                store.ExecuteCommand(query);
            }

        }
    }
}
